﻿#include "adts/aac_adts.h"

#include <iostream>
#include <qdebug.h>
#include <assert.h>

//---------------------------------------------------------------------------
const int ADTS_SamplingRate[]=
{96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
 16000, 12000, 11025,  8000,  7350,     0,     0,     0,};

//---------------------------------------------------------------------------
const char* ADTS_ID[]=
{
    "MPEG-4",
    "MPEG-2",
};

//---------------------------------------------------------------------------
const char* ADTS_Format_Profile[]=
{
    "Main",
    "LC",
    "SSR",
    "LTP",
};

//---------------------------------------------------------------------------
const char* ADTS_Profile[]=
{
    "A_AAC/MPEG4/MAIN",
    "A_AAC/MPEG4/LC",
    "A_AAC/MPEG4/SSR",
    "A_AAC/MPEG4/LTP",
};



CAdtsHeader::CAdtsHeader(char *fileName)
    :m_inputFile(NULL)
    ,m_outFile(NULL)
    ,m_fileName(fileName)
{

    qDebug() << "File name :" << m_fileName.c_str();

    m_inputFile = fopen(m_fileName.c_str(), "rb");
    assert(m_inputFile != NULL);


    m_outFile = fopen("out.txt","wb");


}

int CAdtsHeader::ParseADTSBitstream()
{
    int ret = 0;

    //find_Adts_fff2();

    do
    {
        ret = find_Adts_fff2();
        //解析NAL UNIT
        if (m_nalVec.size())
        {
            for(int i = 0 ; i < m_nalVec.size(); i++)
            {
                fprintf_s(m_outFile, "%02x ",m_nalVec[i]);
            }
            fprintf_s(m_outFile,"\n");

        }

    } while (ret >=0);

    return 0;
}

int  CAdtsHeader::PrintfAdtsInfo()
{

    qDebug() << "fixed_header:";
    qDebug() << "  id                           :" << fixed_header.id;
    qDebug() << "  layer                        :" << fixed_header.layer;
    qDebug() << "  protection_absent            :" << fixed_header.protection_absent;
    qDebug() << "  profile                      :" << fixed_header.profile;
    qDebug() << "  sampling_frequency_index     :" << fixed_header.sampling_frequency_index;
    qDebug() << "  private_bit                  :" << fixed_header.private_bit;
    qDebug() << "  channel_configuration        :" << fixed_header.channel_configuration;
    qDebug() << "  original_copy                :" << fixed_header.original_copy;
    qDebug() << "  home                         :" << fixed_header.home;

    qDebug() <<"id :--   " << ADTS_ID[fixed_header.id];
    qDebug() <<"profile : ---  " << ADTS_Profile[fixed_header.profile];
    qDebug() <<"sampling_frequency_index : ---  " << ADTS_SamplingRate[fixed_header.sampling_frequency_index];



    qDebug() << "variable_header:";

    qDebug() << "copyright_identification_bit         :" << variable_header.copyright_identification_bit;
    qDebug() << "copyright_identification_start       :" << variable_header.copyright_identification_start;
    qDebug() << "aac_frame_length                     :" << variable_header.aac_frame_length;
    qDebug() << "adts_buffer_fullness                 :" << variable_header.adts_buffer_fullness;
    qDebug() << "number_of_raw_data_blocks_in_frame   :" << variable_header.number_of_raw_data_blocks_in_frame;

    if(variable_header.adts_buffer_fullness == 0x7FF)
    {
        qDebug() <<" " << "VBR";
    }
    else
    {
        qDebug() <<" " << "CBR";
    }


    return 0;
}
int	 CAdtsHeader::find_Adts_fff2()
{
    uint8_t header[7] = { 0 };


    if(feof(m_inputFile))
    {
        return -1;
    }

    m_nalVec.clear();

    int getPrefix = 0;


    int idx = 0;
    while (!feof(m_inputFile) && idx < 7)
    {
        header[idx] = getc(m_inputFile);
        m_nalVec.push_back(header[idx]);
        idx ++;
    }

    if(idx < 7)
    {
        return -1;
    }


    if ((header[0] == 0xFF) && ((header[1] & 0xF0)  == 0xF0))
    {
        qDebug() <<"a frame....";
    }

    fixed_header.id =((unsigned int)header[1] & 0x08) >> 3;
    fixed_header.layer = ((unsigned int) header[1] & 0x06) >> 1;
    fixed_header.protection_absent = (unsigned int) header[1] & 0x01;
    fixed_header.profile = ((unsigned int) header[2] & 0xc0) >> 6;
    fixed_header.sampling_frequency_index = ((unsigned int) header[2] & 0x3c) >> 2;
    fixed_header.private_bit = ((unsigned int) header[2] & 0x02) >> 1;
    fixed_header.channel_configuration = ((((unsigned int) header[2] & 0x01) << 2) | (((unsigned int) header[3] & 0xc0) >> 6));
    fixed_header.original_copy = ((unsigned int) header[3] & 0x20) >> 5;
    fixed_header.home = ((unsigned int) header[3] & 0x10) >> 4;

    variable_header.copyright_identification_bit = ((unsigned int) header[3] & 0x08) >> 3;
    variable_header.copyright_identification_start = (unsigned int) header[3] & 0x04 >> 2;
    variable_header.aac_frame_length = (((((unsigned int) header[3]) & 0x03) << 11) | (((unsigned int) header[4] & 0xFF) << 3)| ((unsigned int) header[5] & 0xE0) >> 5) ;
    variable_header.adts_buffer_fullness = (((unsigned int) header[5] & 0x1f) << 6 | ((unsigned int) header[6] & 0xfc) >> 2);
    variable_header.number_of_raw_data_blocks_in_frame = ((unsigned int) header[6] & 0x03);


    PrintfAdtsInfo();


    uint8_t fileByte;

    idx = 0;
    while (!feof(m_inputFile) && idx < variable_header.aac_frame_length-7)
    {
        fileByte = getc(m_inputFile);
        m_nalVec.push_back(fileByte);
        idx++;
    }

    if(idx < variable_header.aac_frame_length-7)
    {
        return -1;
    }

    return 1;
}


CAdtsHeader::CAdtsHeader()
{


}
CAdtsHeader::~CAdtsHeader()
{
    qDebug() <<__FUNCTION__;
    m_nalVec.clear();

    if(m_inputFile)
    {
        fclose(m_inputFile);
        m_inputFile = NULL;
    }

    if(m_outFile)
    {
        fclose(m_outFile);
        m_outFile = NULL;
    }

}
